/*
 * Copyright 2008-2012 the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *       http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.faxsun.api.endpoint.cart;


import org.broadleafcommerce.core.order.domain.Order;
import org.broadleafcommerce.core.order.service.MergeCartService;
import org.broadleafcommerce.core.order.service.OrderService;
import org.broadleafcommerce.core.order.service.call.MergeCartResponse;
import org.broadleafcommerce.core.order.service.exception.RemoveFromCartException;
import org.broadleafcommerce.core.pricing.service.exception.PricingException;
import org.broadleafcommerce.core.web.api.wrapper.OrderWrapper;
import org.broadleafcommerce.core.web.order.CartState;
import org.broadleafcommerce.core.web.service.UpdateCartService;
import org.broadleafcommerce.profile.core.domain.Customer;
import org.broadleafcommerce.profile.core.service.CustomerService;
import org.broadleafcommerce.profile.web.core.CustomerState;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.ws.rs.Consumes;
import javax.ws.rs.DELETE;
import javax.ws.rs.DefaultValue;
import javax.ws.rs.FormParam;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.PUT;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.QueryParam;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.UriInfo;
import javax.xml.bind.annotation.XmlTransient;

/**
 * This is a reference REST API endpoint for cart. This can be modified, used as is, or removed. 
 * The purpose is to provide an out of the box RESTful cart service implementation, but also 
 * to allow the implementor to have fine control over the actual API, URIs, and general JAX-RS annotations.
 * 
 * @author Kelly Tisdell
 *
 */
@Component
@Scope("singleton")
@Path("/cart/")
@Produces(value = { MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML })
@Consumes(value = { MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML })
public class CartEndpoint extends org.broadleafcommerce.core.web.api.endpoint.order.CartEndpoint {
	@XmlTransient 
	@Resource(name="blUpdateCartService")
    protected UpdateCartService updateCartService;
	
	@Resource(name = "blOrderService")
    protected OrderService orderService;
	
	@Resource(name="blCustomerService")
	CustomerService blCustomerService;
	
	@Resource(name = "blMergeCartService")
    protected MergeCartService mergeCartService;
	
    @Override
    @GET
    public OrderWrapper findCartForCustomer(@Context HttpServletRequest request) {
        return super.findCartForCustomer(request);
    }

    @Override
    @POST
    @Consumes("application/x-www-form-urlencoded")
    public OrderWrapper createNewCartForCustomer(@Context HttpServletRequest request) {
        return super.createNewCartForCustomer(request);
    }

    @Override
    @POST
    @Path("{productId}")
    @Consumes("application/x-www-form-urlencoded")
    public OrderWrapper addProductToOrder(@Context HttpServletRequest request,
            @Context UriInfo uriInfo,
            @PathParam("productId") Long productId,
            @FormParam("categoryId") Long categoryId,
            @FormParam("quantity") @DefaultValue("1") int quantity,
            @FormParam("priceOrder") @DefaultValue("true") boolean priceOrder) { 
    	Customer customer = CustomerState.getCustomer(request);
    	if(customer != null){
    		Order cart = orderService.findCartForCustomer(customer);
    	    if (cart == null) {    	
    	        cart = orderService.createNewCartForCustomer(customer);
    	        CartState.setCart(cart);
    	    }
    	}
        return super.addProductToOrder(request, uriInfo, productId, categoryId, quantity, priceOrder);
    }
    
    
    /**
     *匿名用户登录，合并购物车item
     * */
    @POST
    @Path("mergeCart")
    @Consumes("application/x-www-form-urlencoded")
    public OrderWrapper mergeCart(@Context HttpServletRequest request,
    		@FormParam("anonymousCustomer") Long anonymousCustomerId) {  
    	
    	Customer customer = CustomerState.getCustomer(request);
    	Customer anonymousCustomer = blCustomerService.readCustomerById(anonymousCustomerId);
    	
    	MergeCartResponse mergeCartResponse;
    	
    	try {
            Order cart = orderService.findCartForCustomer(anonymousCustomer);
            mergeCartResponse = mergeCartService.mergeCart(customer, cart);
        } catch (PricingException e) {
            throw new RuntimeException(e);
        } catch (RemoveFromCartException e) {
            throw new RuntimeException(e);
        }
    	
    	Order order = mergeCartResponse.getOrder();
    	
    	OrderWrapper wrapper = (OrderWrapper) context.getBean(OrderWrapper.class.getName());
        wrapper.wrapDetails(order, request);

        return wrapper;
    }

    @Override
    @DELETE
    @Path("items/{itemId}")
    public OrderWrapper removeItemFromOrder(@Context HttpServletRequest request,
            @PathParam("itemId") Long itemId,
            @QueryParam("priceOrder") @DefaultValue("true") boolean priceOrder) {
        return super.removeItemFromOrder(request, itemId, priceOrder);
    }

    @Override
    @PUT
    @Path("items/{itemId}")
    @Consumes("application/x-www-form-urlencoded")
    public OrderWrapper updateItemQuantity(@Context HttpServletRequest request,
            @PathParam("itemId") Long itemId,
            @QueryParam("quantity") Integer quantity,
            @QueryParam("priceOrder") @DefaultValue("true") boolean priceOrder) {
        return super.updateItemQuantity(request, itemId, quantity, priceOrder);
    }

    @Override
    @PUT
    @Path("items/{itemId}/options")
    public OrderWrapper updateProductOptions(@Context HttpServletRequest request,
            @Context UriInfo uriInfo,
            @PathParam("itemId") Long itemId,
            @QueryParam("priceOrder") @DefaultValue("true") boolean priceOrder) {
        return super.updateProductOptions(request, uriInfo, itemId, priceOrder);
    }

    @Override
    @POST
    @Path("offer")
    public OrderWrapper addOfferCode(@Context HttpServletRequest request,
            @QueryParam("promoCode") String promoCode,
            @QueryParam("priceOrder") @DefaultValue("true") boolean priceOrder) {
        return super.addOfferCode(request, promoCode, priceOrder);
    }

    @Override
    @DELETE
    @Path("offer")
    public OrderWrapper removeOfferCode(@Context HttpServletRequest request,
            @QueryParam("promoCode") String promoCode,
            @QueryParam("priceOrder") @DefaultValue("true") boolean priceOrder) {
        return super.removeOfferCode(request, promoCode, priceOrder);
    }

    @Override
    @DELETE
    @Path("offers")
    public OrderWrapper removeAllOfferCodes(@Context HttpServletRequest request,
            @QueryParam("priceOrder") @DefaultValue("true") boolean priceOrder) {
        return super.removeAllOfferCodes(request, priceOrder);
    }
    
}
